﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ProxyTool.ControlAnimation;
using ProxyTool.Models;
using ProxyTool.Services;
using ProxyTool.Setting;

namespace ProxyTool.Forms
{
    public partial class ContextDataManagerForm : Form
    {
        private readonly ErrorProvider _errorProvider = new ErrorProvider();

        public ContextDataManagerForm()
        {
            InitializeComponent();
            //加载上下文数据进ListBox
            LoadContextDataListBox();
            if (contextDataListBox.Items.Count == 0)
            {
                //新增一个上下文数据
                AddNewContextData();
            }

            contextDataListBox.SelectedIndex = 0;
            contextDataListBox.Focus();
        }

        /// <summary>
        ///     获取企业
        /// </summary>
        private void GetEnterprises()
        {
            string u9URI = txtU9URI.Text;
            if (string.IsNullOrWhiteSpace(u9URI))
            {
                SetError(btnRefresh, "U9(C)地址不能为空");
                txtU9URI.Focus();
                return;
            }

            List<EnterpriseData> enterpriseDatas = SystemService.GetEnterprises(u9URI);
            if (enterpriseDatas != null && enterpriseDatas.Count > 0)
            {
                foreach (EnterpriseData enterpriseData in enterpriseDatas)
                {
                    ListItem listItem = new ListItem();
                    listItem.Value = enterpriseData;
                    listItem.Text = enterpriseData.Name;
                    cmbEnterprise.Items.Add(listItem);
                }

                cmbEnterprise.SelectedIndex = 0;
            }
        }

        /// <summary>
        ///     获取语言列表
        /// </summary>
        private void GetLanguages()
        {
            string u9URI = txtU9URI.Text;
            if (string.IsNullOrWhiteSpace(u9URI))
            {
                SetError(btnRefresh, "U9(C)地址不能为空");
                txtU9URI.Focus();
                return;
            }

            EnterpriseData enterpriseData = cmbEnterprise.SelectedItem == null
                ? null
                : ((ListItem) cmbEnterprise.SelectedItem).Value as EnterpriseData;
            if (enterpriseData == null) return;
            List<LanguageData> languageDatas = SystemService.GetLanguages(u9URI, enterpriseData.Code);
            if (languageDatas != null && languageDatas.Count > 0)
            {
                foreach (LanguageData languageData in languageDatas)
                {
                    ListItem listItem = new ListItem();
                    listItem.Value = languageData;
                    listItem.Text = languageData.Name;
                    cmbLanguage.Items.Add(listItem);
                }

                cmbLanguage.SelectedIndex = 0;
            }
        }

        /// <summary>
        ///     获取组织
        /// </summary>
        private void GetOrgs()
        {
            string u9URI = txtU9URI.Text;
            if (string.IsNullOrWhiteSpace(u9URI))
            {
                SetError(btnRefresh, "U9(C)地址不能为空");
                txtU9URI.Focus();
                return;
            }

            string userCode = txtUserCode.Text;
            if (string.IsNullOrWhiteSpace(userCode)) return;
            EnterpriseData enterpriseData = cmbEnterprise.SelectedItem == null
                ? null
                : ((ListItem) cmbEnterprise.SelectedItem).Value as EnterpriseData;
            if (enterpriseData == null) return;
            LanguageData languageData = cmbLanguage.SelectedItem == null
                ? null
                : ((ListItem) cmbLanguage.SelectedItem).Value as LanguageData;
            string culture = languageData == null ? "zh-CN" : languageData.Code;
            List<OrgData> orgDatas = SystemService.GetOrgsByUserCode(u9URI, enterpriseData.Code, userCode, culture);
            if (orgDatas != null && orgDatas.Count > 0)
            {
                foreach (OrgData orgData in orgDatas)
                {
                    ListItem listItem = new ListItem();
                    listItem.Value = orgData;
                    listItem.Text = orgData.Name;
                    cmbOrg.Items.Add(listItem);
                }

                cmbOrg.SelectedIndex = 0;
            }
        }

        /// <summary>
        ///     设置错误信息
        /// </summary>
        /// <param name="control"></param>
        /// <param name="errMsg"></param>
        private void SetError(Control control, string errMsg)
        {
            _errorProvider.Clear();
            _errorProvider.SetError(control, errMsg);
            _errorProvider.BlinkStyle = ErrorBlinkStyle.NeverBlink;
        }

        /// <summary>
        ///     加载上下文数据进ListBox
        /// </summary>
        private void LoadContextDataListBox()
        {
            contextDataListBox.Items.Clear();
            if (SettingManagement.Instance.ContextDatas == null ||
                SettingManagement.Instance.ContextDatas.Count == 0) return;
            foreach (ContextData contextData in SettingManagement.Instance.ContextDatas)
            {
                ListItem listItem = new ListItem();
                listItem.Value = contextData;
                listItem.Text = GetContextDataListItemText(contextData);
                contextDataListBox.Items.Add(listItem);
            }
        }

        #region 事件

        #region 控件

        /// <summary>
        ///     名称变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtName_TextChanged(object sender, EventArgs e)
        {
            //更新当前上下文数据
            UpdateCurrentContextData();
        }

        private void txtU9URI_TextChanged(object sender, EventArgs e)
        {
            //更新当前上下文数据
            UpdateCurrentContextData();
        }

        /// <summary>
        ///     企业变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbEnterprise_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbLanguage.Items.Clear();
            cmbLanguage.Text = string.Empty;
            cmbLanguage.SelectedIndex = -1;
            cmbOrg.Items.Clear();
            cmbOrg.Text = string.Empty;
            cmbOrg.SelectedIndex = -1;
            //获取语言列表
            GetLanguages();
            //获取组织
            GetOrgs();
            //更新当前上下文数据
            UpdateCurrentContextData();
        }

        /// <summary>
        ///     语言变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbLanguage_SelectedIndexChanged(object sender, EventArgs e)
        {
            //更新当前上下文数据
            UpdateCurrentContextData();
        }

        /// <summary>
        ///     用户编码变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtUserCode_TextChanged(object sender, EventArgs e)
        {
            cmbOrg.Items.Clear();
            cmbOrg.Text = string.Empty;
            cmbOrg.SelectedIndex = -1;
            //获取组织
            GetOrgs();
            //更新当前上下文数据
            UpdateCurrentContextData();
        }

        /// <summary>
        ///     密码变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtPassword_TextChanged(object sender, EventArgs e)
        {
            //更新当前上下文数据
            UpdateCurrentContextData();
        }

        private void cmbOrg_SelectedIndexChanged(object sender, EventArgs e)
        {
            //更新当前上下文数据
            UpdateCurrentContextData();
        }

        /// <summary>
        ///     上下文数据列表选中变更
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void contextDataListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            _errorProvider.Clear();
            if (contextDataListBox.SelectedIndex < 0) return;
            try
            {
                //禁止事件
                txtName.TextChanged -= txtName_TextChanged;
                txtU9URI.TextChanged -= txtU9URI_TextChanged;
                cmbEnterprise.SelectedIndexChanged -= cmbEnterprise_SelectedIndexChanged;
                cmbLanguage.SelectedIndexChanged -= cmbLanguage_SelectedIndexChanged;
                txtUserCode.TextChanged -= txtUserCode_TextChanged;
                txtPassword.TextChanged -= txtPassword_TextChanged;
                cmbOrg.SelectedIndexChanged -= cmbOrg_SelectedIndexChanged;
                ContextData contextData = contextDataListBox.SelectedItem == null
                    ? null
                    : ((ListItem) contextDataListBox.SelectedItem).Value as ContextData;
                if (contextData == null) return;
                txtName.Text = contextData.Name;
                txtU9URI.Text = contextData.U9URI;
                cmbEnterprise.Items.Clear();
                if (contextData.Enterprise != null)
                {
                    ListItem listItem = new ListItem();
                    listItem.Value = contextData.Enterprise;
                    listItem.Text = contextData.Enterprise == null ? string.Empty : contextData.Enterprise.Name;
                    cmbEnterprise.Items.Add(listItem);
                    cmbEnterprise.SelectedIndex = 0;
                }

                txtUserCode.Text = contextData.UserCode;
                txtPassword.Text = contextData.Password;
                cmbLanguage.Items.Clear();
                if (contextData.Languages != null)
                {
                    for (var i = 0; i < contextData.Languages.Count; i++)
                    {
                        LanguageData languageData = contextData.Languages[i];
                        ListItem listItem = new ListItem();
                        listItem.Value = languageData;
                        listItem.Text = languageData.Name;
                        cmbLanguage.Items.Add(listItem);
                        if (contextData.Language != null && contextData.Language.Code == languageData.Code)
                        {
                            cmbLanguage.SelectedIndex = i;
                        }
                    }
                }

                cmbOrg.Items.Clear();
                if (contextData.Org != null)
                {
                    ListItem listItem = new ListItem();
                    listItem.Value = contextData.Org;
                    listItem.Text = contextData.Org == null ? string.Empty : contextData.Org.Name;
                    cmbOrg.Items.Add(listItem);
                    cmbOrg.SelectedIndex = 0;
                }
            }
            finally
            {
                //恢复事件
                txtName.TextChanged += txtName_TextChanged;
                txtU9URI.TextChanged += txtU9URI_TextChanged;
                cmbEnterprise.SelectedIndexChanged += cmbEnterprise_SelectedIndexChanged;
                cmbLanguage.SelectedIndexChanged += cmbLanguage_SelectedIndexChanged;
                txtUserCode.TextChanged += txtUserCode_TextChanged;
                txtPassword.TextChanged += txtPassword_TextChanged;
                cmbOrg.SelectedIndexChanged += cmbOrg_SelectedIndexChanged;
            }
        }

        /// <summary>
        ///     上下文列表中双击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void contextDataListBox_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (contextDataListBox.SelectedIndex < 0) return;
            DialogResult = DialogResult.OK;
        }

        #endregion

        #region 按钮

        /// <summary>
        ///     刷新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            using (new ControlAnimatorObject(btnRefresh))
            {
                //清理
                cmbEnterprise.Items.Clear();
                cmbEnterprise.Text = string.Empty;
                cmbEnterprise.SelectedIndex = -1;
                cmbLanguage.Items.Clear();
                cmbLanguage.Text = string.Empty;
                cmbLanguage.SelectedIndex = -1;
                cmbOrg.Items.Clear();
                cmbOrg.Text = string.Empty;
                cmbOrg.SelectedIndex = -1;
                //获取企业
                GetEnterprises();
            }
        }

        /// <summary>
        ///     新增
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAdd_Click(object sender, EventArgs e)
        {
            //新增一个上下文数据
            AddNewContextData();
        }

        /// <summary>
        ///     删除按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (contextDataListBox.SelectedIndex < 0) return;
            int selectedIndex = contextDataListBox.SelectedIndex;
            contextDataListBox.Items.RemoveAt(selectedIndex);
            selectedIndex--;
            contextDataListBox.SelectedIndex =
                selectedIndex >= 0 ? selectedIndex : contextDataListBox.Items.Count > 0 ? 0 : -1;
        }

        /// <summary>
        ///     保存按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            //保存所有上下文数据
            SaveContextDatas();
            Close();
        }

        /// <summary>
        ///     保存并应用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnApply_Click(object sender, EventArgs e)
        {
            try
            {
                //保存所有上下文数据
                SaveContextDatas();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "设置异常");
                DialogResult = DialogResult.None;
            }
        }

        /// <summary>
        ///     移动到顶端
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMoveToTop_Click(object sender, EventArgs e)
        {
            if (contextDataListBox.SelectedIndex <= 0) return;
            object item = contextDataListBox.SelectedItem;
            contextDataListBox.Items.RemoveAt(contextDataListBox.SelectedIndex);
            contextDataListBox.Items.Insert(0, item);
            contextDataListBox.SelectedIndex = 0;
        }

        private void btnMoveUp_Click(object sender, EventArgs e)
        {
            if (contextDataListBox.SelectedIndex <= 0) return;
            object item = contextDataListBox.SelectedItem;
            int selectedIndex = contextDataListBox.SelectedIndex;
            contextDataListBox.Items.RemoveAt(contextDataListBox.SelectedIndex);
            contextDataListBox.Items.Insert(selectedIndex - 1, item);
            contextDataListBox.SelectedIndex = selectedIndex - 1;
        }

        private void btnMoveDown_Click(object sender, EventArgs e)
        {
            if (contextDataListBox.SelectedIndex < 0) return;
            if (contextDataListBox.SelectedIndex == contextDataListBox.Items.Count - 1) return;
            object item = contextDataListBox.SelectedItem;
            int selectedIndex = contextDataListBox.SelectedIndex;
            contextDataListBox.Items.RemoveAt(contextDataListBox.SelectedIndex);
            contextDataListBox.Items.Insert(selectedIndex + 1, item);
            contextDataListBox.SelectedIndex = selectedIndex + 1;
        }

        private void btnMoveToBottom_Click(object sender, EventArgs e)
        {
            if (contextDataListBox.SelectedIndex < 0) return;
            if (contextDataListBox.SelectedIndex == contextDataListBox.Items.Count - 1) return;
            object item = contextDataListBox.SelectedItem;
            contextDataListBox.Items.RemoveAt(contextDataListBox.SelectedIndex);
            contextDataListBox.Items.Add(item);
            contextDataListBox.SelectedIndex = contextDataListBox.Items.Count - 1;
        }

        /// <summary>
        ///     新增一个上下文数据
        /// </summary>
        private void AddNewContextData()
        {
            ContextData contextData = new ContextData();
            ListItem listItem = new ListItem();
            listItem.Value = contextData;
            listItem.Text = GetContextDataListItemText(contextData);
            contextDataListBox.Items.Add(listItem);
            contextDataListBox.SelectedIndex = contextDataListBox.Items.Count - 1;
        }

        /// <summary>
        ///     更新当前上下文数据
        /// </summary>
        private void UpdateCurrentContextData()
        {
            _errorProvider.Clear();
            if (contextDataListBox.SelectedIndex < 0) return;
            try
            {
                //禁止事件
                contextDataListBox.SelectedIndexChanged -= contextDataListBox_SelectedIndexChanged;
                string name = txtName.Text;
                string u9URI = txtU9URI.Text;
                EnterpriseData enterpriseData = cmbEnterprise.SelectedItem == null
                    ? null
                    : ((ListItem) cmbEnterprise.SelectedItem).Value as EnterpriseData;
                LanguageData languageData = cmbLanguage.SelectedItem == null
                    ? null
                    : ((ListItem) cmbLanguage.SelectedItem).Value as LanguageData;
                List<LanguageData> languageDatas = new List<LanguageData>();
                foreach (object item in cmbLanguage.Items)
                {
                    LanguageData languageData2 = item == null
                        ? null
                        : ((ListItem) item).Value as LanguageData;
                    if (languageData2 == null) continue;
                    languageDatas.Add(languageData2);
                }

                string userCode = txtUserCode.Text;
                string password = txtPassword.Text;
                OrgData orgData = cmbOrg.SelectedItem == null
                    ? null
                    : ((ListItem) cmbOrg.SelectedItem).Value as OrgData;
                ContextData contextData = new ContextData();
                contextData.Name = name;
                contextData.U9URI = u9URI;
                contextData.Enterprise = enterpriseData;
                contextData.Language = languageData;
                contextData.Languages = languageDatas;
                contextData.UserCode = userCode;
                contextData.Password = password;
                contextData.Org = orgData;
                ListItem listItem = new ListItem();
                listItem.Value = contextData;
                listItem.Text = GetContextDataListItemText(contextData);
                contextDataListBox.Items[contextDataListBox.SelectedIndex] = listItem;
            }
            finally
            {
                //恢复事件
                contextDataListBox.SelectedIndexChanged += contextDataListBox_SelectedIndexChanged;
            }
        }

        /// <summary>
        ///     保存所有上下文数据
        /// </summary>
        private void SaveContextDatas()
        {
            List<ContextData> contextDatas = new List<ContextData>();
            foreach (object item in contextDataListBox.Items)
            {
                ContextData contextData = item == null
                    ? null
                    : ((ListItem) item).Value as ContextData;
                if (contextData == null) return;
                contextDatas.Add(contextData);
            }

            SettingManagement.Instance.SaveContextDatas(contextDatas);
        }

        /// <summary>
        ///     获取返回结果
        /// </summary>
        /// <returns></returns>
        public ContextData GetReturnContextData()
        {
            if (contextDataListBox.SelectedIndex < 0) return null;
            ListItem listItem = contextDataListBox.SelectedItem as ListItem;
            return listItem?.Value as ContextData;
        }

        /// <summary>
        ///     获取上下文数据列表显示名
        /// </summary>
        /// <param name="contextData"></param>
        /// <returns></returns>
        public static string GetContextDataListItemText(ContextData contextData)
        {
            if (contextData == null || string.IsNullOrEmpty(contextData.Name)) return string.Empty;
            return contextData.Name;
            List<string> txtList = new List<string>();
            if (!string.IsNullOrEmpty(contextData.Name)) txtList.Add(contextData.Name);
            if (!string.IsNullOrEmpty(contextData.U9URI)) txtList.Add(contextData.U9URI);
            if (contextData.Enterprise != null && !string.IsNullOrEmpty(contextData.Enterprise.Name))
                txtList.Add(contextData.Enterprise.Name);
            if (contextData.Org != null && !string.IsNullOrEmpty(contextData.Org.Name))
                txtList.Add(contextData.Org.Name);
            if (!string.IsNullOrEmpty(contextData.UserCode)) txtList.Add(contextData.UserCode);
            return string.Join("-", txtList);
        }

        #endregion

        #endregion
    }
}